package interfaces.subpanel.cargardatos.gui;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.table.AbstractTableModel;

import model.GenericScenarie;

import org.apache.commons.collections.CollectionUtils;

import comparators.GenericScenarieComparator;

import enumerations.AttributesEnum;

/**
 * My table model consist in two columns. The first column contains the
 * attribute associated to the general scenarie. The second column contains the
 * general scenarie itself.
 */
public class MyTableModel extends AbstractTableModel {

	private static final long serialVersionUID = 1L;

	private static final String ATTRIBUTE_COLUMN_NAME = "Attribute";

	private static final String GENERAL_SCENARIE_COLUMN_NAME = "General Scenarie";

	private String[] columnNames = { ATTRIBUTE_COLUMN_NAME,
			GENERAL_SCENARIE_COLUMN_NAME };

	private List<GenericScenarie> data = new ArrayList<GenericScenarie>();

	private GenericScenarieComparator genericScenarieComparator = new GenericScenarieComparator();

	public int getColumnCount() {
		return this.columnNames.length;
	}

	public int getRowCount() {
		return this.data.size();
	}

	public String getColumnName(int col) {
		return this.columnNames[col];
	}

	public Object getValueAt(int row, int col) {
		if (this.data.size() <= row) {
			System.out
					.println("ERROR: Out of Index while getting data from model in table.");
			return null;
		}
		GenericScenarie scenarie = this.data.get(row);
		if (col == 0)
			return (AttributesEnum) scenarie.getAttribute();
		else
			return (String) scenarie.getScenarie();
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public Class getColumnClass(int c) {
		return getValueAt(0, c).getClass();
	}

	public boolean isCellEditable(int row, int col) {
		if (col == 0) {
			return true;
		} else {
			return false;
		}
	}

	public void addItem(GenericScenarie genericScenarie) {
		if (genericScenarie != null) {
			this.data.add(genericScenarie);
			Collections.sort(this.data, this.genericScenarieComparator);
			fireTableDataChanged();
		}
	}

	public void addAllGenericScenaries(List<GenericScenarie> genericScenaries) {
		if (CollectionUtils.isNotEmpty(genericScenaries)) {
			this.data.addAll(genericScenaries);
			Collections.sort(this.data, this.genericScenarieComparator);
			fireTableDataChanged();
		}
	}

	public void setValueAt(Object value, int row, int col) {
		if (data.size() <= row) {
			System.out
					.println("ERROR: Out of Index while setting data into data model in table.");
			return;
		}
		if (col == 0) {
			data.get(row).setAttribute((AttributesEnum) value);
		} else {
			data.get(row).setScenarie((String) value);
		}
		fireTableCellUpdated(row, col);
	}

	public int dataSize() {
		return this.data.size();
	}

	public boolean isEmpty() {
		return CollectionUtils.isEmpty(this.data);
	}

	public boolean isNotEmpty() {
		return !this.isEmpty();
	}

	public GenericScenarie getGenericScenarie(int index) {
		GenericScenarie genericScenarie = null;
		if (this.data.size() > index)
			genericScenarie = this.data.get(index);
		return genericScenarie;
	}

	public void removeGenericScenarie(int index) {
		if (this.data.size() > index) {
			this.data.remove(index);
			fireTableDataChanged();
		}
	}

	public List<GenericScenarie> removeIndexes(int[] genericScenariesIndexes) {

		List<GenericScenarie> removedScenaries = new ArrayList<GenericScenarie>();
		List<GenericScenarie> notRemovedScenaries = new ArrayList<GenericScenarie>();
		if (CollectionUtils.isNotEmpty(this.data)) {
			int i = 0, j = 0;
			while (i < genericScenariesIndexes.length) {
				int indexToRemove = genericScenariesIndexes[i];
				while (j < this.data.size()) {
					if (j == indexToRemove) {
						removedScenaries.add(this.data.get(indexToRemove));
						if (i < genericScenariesIndexes.length - 1)
							break;
					} else
						notRemovedScenaries.add(new GenericScenarie(this.data
								.get(indexToRemove).getId(), this.data.get(
								indexToRemove).getAttribute(), this.data.get(
								indexToRemove).getScenarie(), this.data.get(
								indexToRemove).getProjectId()));
					j++;
				}
				i++;
			}
			this.data.removeAll(removedScenaries);
			fireTableDataChanged();
		}

		return removedScenaries;
	}

	public void removeAllGenericScenaries() {
		this.data.clear();
		fireTableDataChanged();
	}

	public List<GenericScenarie> getAllGenericScenaries() {
		if (this.data == null)
			this.data = new ArrayList<GenericScenarie>();
		return this.data;
	}

}
